package com.base.lib.base.view

import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.jeremyliao.liveeventbus.LiveEventBus
import com.base.lib.R
import com.base.lib.base.mvvm.repository.BaseRepository
import com.base.lib.base.mvvm.viewmodel.BaseViewModel
import com.base.lib.base.utils.ext.view.showToast
import com.base.lib.httpUtils.utils.NetWorkUtil
import kotlinx.coroutines.TimeoutCancellationException
import retrofit2.HttpException
import kotlin.coroutines.cancellation.CancellationException

/**
 * Describe:
 * 基础 MVVM 页面
 *
 */
abstract class BaseMvvmFragment<VM : BaseViewModel> : BaseFragment() {
    protected val mViewModel: VM by lazy { ViewModelProvider(this).get(onBindViewModel()) }

    private var isShowNetTip = false

    override fun initCommonView(view: View) {
        super.initCommonView(view)
        initBaseViewObservable()
        initViewObservable()
    }

    /**
     * 带有网络错误提示header
     */
    protected fun initNetTipView() {
        isShowNetTip = true;
        initTopView(R.layout.layout_network_err_tip)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        if (isShowNetTip){
            //        //初始化网络出错的View
            val mTipView = findViewById<View>(R.id.ll_net_error_tip)
            mTipView.setOnClickListener {
                //跳转到系统设置页面
                startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS))
            }
            //首次启动要判断一下，不然会始终显示网络错误的View
            if (NetWorkUtil.isNetworkConnected(requireActivity()))
                mTipView.visibility = View.GONE
            //初始化网络状态的LiveData
            LiveEventBus.get("isConnected", Boolean::class.java).observe(this) {
                if (it) {
                    initData()
                    mTipView.visibility = View.GONE
                } else {
                    mTipView.visibility = View.VISIBLE
                }
            }
        }
    }

    /**
     * 绑定 ViewModel
     */
    abstract fun onBindViewModel(): Class<VM>

    /**
     * 放置 观察者对象
     */
    protected open fun initViewObservable(){}


    /**
     * 初始化页面观察 变更相应的展示
     */
    protected open fun initBaseViewObservable() {
        // 将 Frament 的生命周期同步到 ViewModel 中
        lifecycle.addObserver(mViewModel)

        mViewModel.mUIChangeLiveData.getShowToastViewEvent()
            .observe(this) { it.showToast() }
        mViewModel.mUIChangeLiveData.getShowInitLoadViewEvent()
            .observe(this) {
                showInitLoadView(it)
            }
        mViewModel.mUIChangeLiveData.getShowTransLoadingViewEvent()
            .observe(this) {
                showTransLoadingView(it)
            }
        mViewModel.mUIChangeLiveData.getShowNoDataViewEvent()
            .observe(this) {
                showNoDataView(it)
            }
        mViewModel.mUIChangeLiveData.getShowNetWorkErrViewEvent()
            .observe(this) {
                showNetWorkErrView(it)
            }
        mViewModel.mUIChangeLiveData.getStartActivityEvent()
            .observe(this) {
                val clz =
                    it[BaseViewModel.ParameterField.CLASS] as Class<*>?
                val bundle = it[BaseViewModel.ParameterField.BUNDLE] as Bundle?
                startActivity(clz, bundle)
            }
        mViewModel.mUIChangeLiveData.getFinishActivityEvent()
            .observe(this) { mActivity.finish() }
        mViewModel.mUIChangeLiveData.getOnBackPressedEvent()
            .observe(this) { mActivity.onBackPressed() }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        startObserve()
    }

    private fun startObserve() {
        //处理一些通用异常，比如网络超时等
        mViewModel.run {
            getError().observe(requireActivity()) {
                requestError(it)
            }
            getFinally().observe(requireActivity()) {
                requestFinally(it)
            }
        }
    }

    open fun requestFinally(it: Int?) {

    }

    open fun requestError(it: Exception?) {
        //处理一些已知异常
        it?.run {
            when (it) {
                is CancellationException -> Log.d("${TAG}--->接口请求取消", it.message.toString())
                is TimeoutCancellationException -> "请求超时".showToast()
                is BaseRepository.TokenInvalidException -> "登陆超时".showToast()
                is HttpException -> { if (it.code() == 504) "无法连接服务器,请检查网络设置".showToast() else it.message.toString().showToast() }
                else -> it.message.toString().showToast()
            }
        }
    }
}
